#include <io.h>
#include <stdio.h>
#include <string.h>
#include <system.h>
#include <altera_avalon_pio_regs.h>
#include "mdio_reg_wr.h"
#include "../utility.h"

alt_u8 mdio_reg_0_wr(viod)
{
	reg0_t 		reg0;

	reg0.reset			= 0;
	reg0.loopback		= 0;
	reg0.speed0			= 0;
	reg0.an_ena			= 1;
	reg0.power_down		= 0;
	reg0.isolate		= 0;
	reg0.restart		= 0;
	reg0.duplex_mode	= 1;
	reg0.col_test		= 0;
	reg0.speed1			= 0;
	reg0.res			= 0;

	mdio_reg_wr(16, 0, reg0.data);


//  reg0.reset			= 1;
//	mdio_reg_wr(16, 0, reg0.data);

	return 0;

}

alt_u8 mdio_reg_16_wr(viod)
{
	reg16_t 		reg16;

	reg16.tx_fifo_depth		= 2;
	reg16.rx_fifo_depth		= 2;
	reg16.crs_mode			= 0;
	reg16.forse_link_good	= 1;
	reg16.energy_detect		= 0;
	reg16.ext_dist			= 0;
	reg16.cross_mode		= 3;
	reg16.dsbl_125clk		= 0;
	reg16.mac_pow_down		= 1;
	reg16.sqe_test			= 0;
	reg16.polarity			= 1;
	reg16.dis_jubber		= 1;

	mdio_reg_wr(16, 16, reg16.data);


	return 0;

}

alt_u8 mdio_reg_wr(alt_u8 phy_addr, alt_u8 reg_addr, alt_u16 reg_data)
{
	alt_u8		err = 0;
	msg_mdio_t	msg;
	int 		i = 0;
	alt_u32 	data_reg;
	alt_u16		tmp;


	// Отправим 32 единицы
	IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 1 << 10);
	for (i=0; i<31; i++)
	{
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (1 << 11) | (1 << 10));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 1 << 10);
	};

	msg.start 		= 1;
	msg.opcode		= 1;
	msg.phy_addr	= phy_addr;
	msg.reg_addr	= reg_addr;
	msg.ta			= 2;
	msg.reg_data	= reg_data;


	// Отправим start
	for (i=1; i>=0; i--)
	{
		tmp = (msg.start >> i) & 1;
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10) | (1 << 11));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
	};

	// Отправим код
	for (i=1; i>=0; i--)
	{
		tmp = (msg.opcode >> i) & 1;
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10) | (1 << 11));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
	};

	// Отправим адрес
	for (i=4; i>=0; i--)
	{
		tmp = (msg.phy_addr >> i) & 1;
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10) | (1 << 11));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
	};

	for (i=4; i>=0; i--)
	{
		tmp = (msg.reg_addr >> i) & 1;
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10) | (1 << 11));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
	};

	for (i=1; i>=0; i--)
	{
		tmp = (msg.ta >> i) & 1;
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10) | (1 << 11));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
	};

	for (i=15; i>=0; i--)
	{
		tmp = (msg.reg_data >> (15 - i)) & 1;
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10) | (1 << 11));
		usleep(1);
		IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (tmp << 10));
	};

	return err;
}

